package com.vue.backend.api;

import java.util.*;
import java.util.Map.Entry;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
import java.util.stream.Stream;

/**
 * @ClassName: JavaStream
 * @Description:
 * @author: 郭秀志 jbcode@126.com
 * @date: 2020/5/3 20:15
 * @Copyright:
 */
public class JavaStream {
    public static void myPrint(String str) {
        System.out.println("自定义方法的str = " + str);
    }

    public static void main(String[] args) {


        int[] nums = {2, 3, 80, -1, 4, 52, 0, 70};
        Arrays.stream(nums).sorted().forEach(x -> System.out.println(x));

        System.out.println("和" + Arrays.stream(nums).sum());
        System.out.println("平均" + Arrays.stream(nums).average().orElse(0));
        String[] strs = {"20", "111", "12", "4", "3", "5"};
        System.out.println("max" + Arrays.stream(strs).sorted((o1, o2) -> o1.compareTo(o2)).flatMapToInt(s -> IntStream.of(Integer.parseInt(s))).findAny().getAsInt());

        Arrays.stream(strs).peek(JavaStream::myPrint).filter(s -> Integer.parseInt(s) > 3).collect(Collectors.toMap(s -> "key" + s, s -> s)).forEach(JavaStream::accept);
        System.out.println("args = " + Arrays.stream(strs).peek(JavaStream::myPrint).filter(s -> Integer.parseInt(s) > 3).reduce("", (s, s2) -> {
            if (s2.length() < 2) {
                s = s.concat(",").concat(s2);
            }
            return s;
        }));
        System.out.println("和" + Arrays.stream(nums).reduce((left, right) -> Math.min(left, right)).getAsInt());

        Arrays.stream(strs).peek(JavaStream::myPrint).filter(s -> Integer.parseInt(s) > 3).sorted(Comparator.comparing(String::trim).reversed()).collect(Collectors.toList()).forEach(System.out::println);

        Map<String, String> params = new HashMap<String, String>();
        params.put("age", "12");
        params.put("location", "中国");
        params.put("zoo", "cat");
        params.put("name", "guo");
        params.put("go", "school");

        String collect1 = params.entrySet().stream().sorted(Comparator.comparing(Entry::getKey)).map(entry -> entry.getKey() + "=" + entry.getValue()).collect(Collectors.joining("&"));
//        System.out.println("collect1 = " + collect1);

        Integer reduce = Stream.of(1, 2, 3, 4, 5).parallel().reduce(0, (integer, integer2) -> {
                    System.out.println(Thread.currentThread().getName() + "累加器integer = " + integer + "累加器integer2 = " + integer2);
                    return integer + integer2;
                }
                , (integer, integer2) -> {
                    System.out.println(Thread.currentThread().getName() + "合并integer = " + integer + "合并integer32 = " + integer2);
                    return integer + integer2;
                });
        System.out.println("reduce = " + reduce);

        //1. 给定一段英文句子，单词用空格间隔
        String words = "stream xiu zhi zhi guo map reduce hadoop java stream guostream parallel guo";
        //2.1  由于是多线程要使用 ConcurrentHashMap，HashMap不支持并发操作
        //2.2  给定语句通过空格分割成数组，转换成普通Stream，再转换并行流
        //2.3  并行流进行三参数的reduce计算。第一个参数是返回值，第二个参数是累加器，第三个参数是各个线程返回值的合并操作。


        Lock lock = new ReentrantLock();
        ConcurrentHashMap<String, Integer> reduceMap = Arrays.stream(words.split(" ")).parallel().reduce(new ConcurrentHashMap<String, Integer>(), (map, w) -> {
            return getStringIntegerConcurrentHashMap(map, w);
        }, (m1, m2) -> {
            //把并行计算的各个结果归并整合到m1中，m1和m2是一个对象，所以直接返回m1
            System.out.println(Thread.currentThread().getName() + "," + (m1 == m2));
            return m1;
        });

        //根据单词的出现次数倒序排列后输出到List对象
        List<Entry<String, Integer>> collect = reduceMap.entrySet().stream().sorted((o1, o2) -> o2.getValue() - o1.getValue()).collect(Collectors.toList());
        //输出排序后的list数据
        System.out.println("reduceMap = " + collect);

        ConcurrentMap<String, Integer> toConcurrentMap = Arrays.stream(words.split(" ")).parallel().collect(Collectors.toConcurrentMap(s -> s, s -> 1,
                (integer, integer2) -> integer + integer2));
        Map<String, Integer> collect2 = Arrays.stream(words.split(" ")).parallel().collect(Collectors.toMap(s -> s, s -> 1,
                (integer, integer2) -> integer + integer2));
        List<Entry<String, Integer>> orderedCollection = collect2.entrySet().stream().sorted((o1, o2) -> o2.getValue() - o1.getValue()).collect(Collectors.toList());
        System.out.println("reduceMap = " + orderedCollection);


        Stream stream = Stream.of("a1", "a1", "b1", "c1");// stream has already been operated upon or closed
        Object str = stream.collect(Collectors.groupingBy(Function.identity(), Collectors.counting()));
        System.out.print(str); // {a1=2, c1=1, b1=1}

        // Partition students into passing and failing


//        System.out.println("LocalCacheUtil.get(\"guo\") = " + LocalCacheUtil.get("guo"));
    }

    public synchronized static ConcurrentHashMap<String, Integer> getStringIntegerConcurrentHashMap(ConcurrentHashMap<String, Integer> map, String w) {
        Integer num = map.get(w);
        if (num == null) {//这个单词如果不存在于map中
            map.put(w, 1);
        } else {//这个单词如果存在于map中，数量+1，新值放入map
            map.put(w, num + 1);
        }
        return map;
    }

    private static void accept(String s, String s2) {
        System.out.println("自定义方法--key:" + s + ",value:" + s2);
    }


}